#ifndef _YEP_VIDEO_TILEMAP_HPP
#define _YEP_VIDEO_TILEMAP_HPP

#include "../common.hpp"

#include <vector>

#include "Image.hpp"
#include "../math/Vector2.hpp"

namespace yep
{

class Tileset;

/**
 * @brief A map made from a tileset
 **/
class Tilemap: public Image
{
public:
    /**
     * @brief The default constructor. Calling this allow the use of the setter width(unsigned), height(unsigned)
     *  and tileset once.
     **/
    Tilemap();
    /**
     * @brief Create the map using the parameters
     **/
    Tilemap( Tileset &tileset, unsigned mapWidth, unsigned mapHeight );

    /**
     * @brief Create the map using the iterators;
     *
     * @tparam T An iterator compliant class. It must be fowarded (right ++), compared (!=), assigned and
     *  derreferenced.
     *
     * @param tileset the tileset.
     * @param mapWidth the map width.
     * @param iteratorBegin The first element. It will start assigning iteratorBegin to the iterator.
     * @param iteratorEnd The after end element. It will stop the copy when the iterator is equal iteratorEnd
     **/
    template<class T>
    Tilemap( Tileset &tileset, unsigned mapWidth, T iteratorBegin, T iteratorEnd );

    /**
     * @brief Creates based on a initialization list.
     *
     * Only tiles are in the list. The tileset and size is passed on setters.
     **/
    Tilemap( const initializer_list<int> &list );

    /**
     * @brief Destructor
     **/
    ~Tilemap();

    /**
     * @brief Get/Set the tile at given position
     **/
    int &operator[]( const Vector2 &position);

    /**
     * @brief Returns the tileWidth
     **/
    unsigned getMapWidth() const
    {
        return mapWidth;
    }

    /**
     * @brief Returns the mapHeigtht
     **/
    unsigned getMapHeight() const
    {
        return mapHeight;
    }

    /**
     * @brief Returns the tileset
     **/
    Tileset &getTileset() const
    {
        return *tileset;
    }

    /**
     * @brief Sets the map width.
     *
     * Can be called only once, after the default constructor or initilizer_list constructor.
     **/
    Tilemap &setMapWidth( unsigned value );

    /**
     * @brief Sets the map height
     *
     * Can be called only once, after the default constructor or initilizer_list constructor.
     **/
    Tilemap &setMapHeight( unsigned value );

    /**
     * @brief Sets the tileset.
     *
     * Can be called only once, after the default constructor or initilizer_list constructor.
     **/
    Tilemap &setTileset( Tileset &value );

    /**
     * @see Drawable
     **/
    virtual void draw( Canvas &canvas, const Vector2 &position );

    /**
     * @see Drawable
     **/
    virtual void draw( Canvas &canvas, const Vector2 &position, const Vector2 &sectionPosition, const Vector2 &sectionSize );
private:
    unsigned mapWidth, mapHeight;
    Tileset *tileset;
    vector<int> tiles;
};

}

#endif // _YEP_VIDEO_TILEMAP_HPP

